#include "stdafx.h"
#include "ASN1Integer.h"

namespace AppliedCryptography
{
	ASN1Integer::ASN1Integer(ClassBits classBits, ConstructedBit constucted, TypeNumberBits number)
		: ASN1Encodable(classBits, constucted, number),
		_value(0)
	{
	};

	ASN1Integer::ASN1Integer(ClassBits classBits, ConstructedBit constucted, TypeNumberBits number, int value)
		: ASN1Encodable(classBits, constucted, number),
		_value(value)
	{
	};

	ASN1Integer::ASN1Integer()
		: ASN1Encodable(Universal, Primitive, Integer),
		_value(0)
	{
	};

	ASN1Integer::ASN1Integer(int value)
		: ASN1Encodable(Universal, Primitive, Integer),
		_value(value)
	{
	};

	void ASN1Integer::set(int value)
	{
		_value = value;
	};

	void ASN1Integer::operator=(int value)
	{
		this->set(value);
	};

	int ASN1Integer::get() const
	{
		return _value;
	};

	/*
	std::vector<byte> ASN1Integer::getLengthBits() const
	{
		std::vector<byte> v;
		v.push_back(this->getContentBits().size());
		return v;
	};
	*/

	std::vector<byte> ASN1Integer::getContentBits() const
	{
		std::vector<byte> v;
		int val = this->get();
		bool fLongFormInit = false;

		if(val < -128)
		{
			val *= -1;
			while(val >= 256 || !fLongFormInit)
			{
				v.insert(v.begin(), 0xFF - (val % 256) + 1);
				val = (val - val % 256) / 256;
				fLongFormInit = true;
			};
			v.insert(v.begin(), (0xFF - val) | 0x80);
		}
		else if(val < 0)
		{
			v.push_back((val * -1 % 128) | 0x80);
		}
		else if(val < 128)
		{
			v.push_back(val % 128);
		}
		else
		{
			while(val > 255 || !fLongFormInit)
			{
				v.insert(v.begin(), val % 256);
				val = (val - val % 256) / 256;
				fLongFormInit = true;
			};
			v.insert(v.begin(), val);
		};

		return v;
	};

	ASN1Integer ASN1Integer::getInstance(ASN1Encodable& obj)
	{
		ASN1Integer integer;

		if(obj.getTypeBits() == integer.getTypeBits())
		{
			return *(ASN1Integer*)&obj;
		};

		throw std::exception("Unknow object in getInstance()!");
	};
}; // namespace AppliedCryptography
